#include "cli_wrapper.h"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
using namespace boost;
bool CLIPath::Initialize(	const std::string& separator,
				const std::string& initPath ){
	mSeparator = separator;
	return RevisePath(initPath);
}

bool CLIPath::RevisePath( const std::string& path ){
	std::string trimPathVec = trim_copy( path ); 
	if( !trimPathVec.empty() ){
		std::vector<std::string> subDirVec;
		ParsePath( path, subDirVec );	
		bool fromRoot = false;
		if( mSeparator[0] == trimPathVec[0] ){
			fromRoot = true;
		}
		MergePath( subDirVec, fromRoot );
	}
	return true;
}

void CLIPath::ParsePath( const std::string& path, std::vector<std::string>& pathVec ){
	split(	pathVec, path, boost::algorithm::is_any_of(mSeparator), token_compress_off );
	return;
}
void CLIPath::MergePath( const std::vector<std::string>& pathVec, bool fromRoot ){
	if( fromRoot ){
		SetPathVec( pathVec );
	}else{
		mPathVec.insert( mPathVec.end(), pathVec.begin(), pathVec.end() );
	}
	while(true){
		bool complate = true;
		std::vector<std::string>::iterator iter2= mPathVec.begin();
		std::vector<std::string>::iterator iter1 = iter2++; 
		for(; iter1 != mPathVec.end(); iter1=iter2++ ){
			if( *iter1 == "." || *iter1 == ".." || iter1->empty() ){
				mPathVec.erase(iter1);
				complate = false;
				break;
			}else{
				if( iter2 != mPathVec.end() ){
					if( *iter2 == ".." ){
						mPathVec.erase(iter2);
						mPathVec.erase(iter1);
						complate = false;
						break;
					}
				}
			}
		}
		if( complate ){
			break;
		}
	};
}

std::string CLIPath::BuildPath() const{
	std::string path = mSeparator;
	std::vector<std::string>::const_iterator iter;
	for( iter = mPathVec.begin(); iter != mPathVec.end(); iter++ ){
		path += *iter;
		path += mSeparator;
	}
	return path;
}

CLIWrapper::CLIWrapper(){
}

CLIWrapper::~CLIWrapper(){
}

bool CLIWrapper::Initialize(	const std::string& prefix,
				const std::string& suffix,
				const std::string& prompt,
				const std::string& separator,
				const std::string& initPath){
	mPrefix = prefix;
	mSuffix = suffix;
	mPrompt = prompt;
	return CLIPath::Initialize( separator, initPath );
}

std::string CLIWrapper::BuildPrompt() const{
	std::string prompt = mPrefix + BuildPath()+mSuffix+ mPrompt;
	return prompt;
}

char * CLIWrapper::GetLine( const std::string& path, const std::string& prompt){
	char * content = readline( BuildPrompt().c_str() );
	return content;
	
}

void CLIWrapper::AppendPath( const std::string& subPath ){
	mPathVec.push_back( subPath );
	return;
}

